package ex1;

public class Queue<T> {
	protected int size;     	// number of elements in the queue
    protected Node first;    	// beginning of queue
    protected Node last;    	// end of queue

    /**
     * Node class
     */
    protected class Node {
    	protected T item;
        protected Node next;
    }

    /**
     * Constructor
     */
    public Queue() {
        size = 0;
    	first = null;
        last  = null;
    }
    
    /**
     * IsEmpty
     */
    public boolean isEmpty() {
        return (first == null);
    }

    /**
     * size
     * @return size of queue
     */
    public int size() {
        return size;     
    }

    /**
     * Enqueue - adds item to queue (SYNCHRONIZED)
     * @param item - item to add to queue
     */
    public boolean enqueue(T item) {
        Node node = new Node();
        node.item = item;
        if (isEmpty()) {
        	first = node;
        	last = node;
        } else {
        	last.next = node;
        	last = node;
        }
        size++;
        return true; //succeeded
    }

    /**
     * Dequeue - remove first item from queue (SYNCHRONIZED) 
     * @return first item of queue that has been removed
     */
    public T dequeue() {
        if (isEmpty()) {
        	return null;
        }
        T item = first.item;
        first = first.next;
        size--;
        if (isEmpty()) {
        	last = null;
        }
        return item;
    }
}
